// -----------------------------
// Author: 		Dhaenens Gert 
// Creation: 	8/4/2013 12:40:22 PM				
// -----------------------------

#ifndef _LuaScript_h
#define _LuaScript_h

#include "ObjectLuaCommon.h"
#include "LuaObject.h"
#include "LuaRef.h"
#include "LuaVariable.h"

namespace ObjectLua
{

	/*
	// Lua Script Object
	*/
	class OBJECTLUA LuaScript : public LuaObject
	{
	public:
		LuaScript(Lua* lpLua, const char* filePath);
		LuaScript(const LuaScript& refLuaScript);
		LuaScript& operator=(const LuaScript& refLuaScript);
		virtual ~LuaScript();

		/*
		//	Load the Script onto the stack
		*/
		virtual void	load();
		/*
		//	Unload the Script from the stack
		*/
		virtual void	unload();
		/*
		//	Reload the Script
		*/
		virtual void	reload();
		/*
		//	Run the Script
		*/
		virtual void	run();


		/*
		//	Get a variable from the Script
		//	@ Name : variable name
		*/
		virtual LuaVariable getVariable(const char* Name);


		/*
		//	Call a Function in the Script
		//	0 Arguments, no return
		*/
		void			callFunction(const char* name);
		/*
		//	Call a Function in the Script
		//	1 Arguments, no return
		*/
		template<typename P0>
		void			callFunction(const char* name, P0 arg1);
		/*
		//	Call a Function in the Script
		//	2 Arguments, no return
		*/
		template<typename P0, typename P1>
		void			callFunction(const char* name, P0 arg1, P1 arg2);
		/*
		//	Call a Function in the Script
		//	3 Arguments, no return
		*/
		template<typename P0, typename P1, typename P2>
		void			callFunction(const char* name, P0 arg1, P1 arg2, P2 arg3);
		/*
		//	Call a Function in the Script
		//	4 Arguments, no return
		*/
		template<typename P0, typename P1, typename P2, typename P3>
		void			callFunction(const char* name, P0 arg1, P1 arg2, P2 arg3, P3 arg4);
		/*
		//	Call a Function in the Script
		//	5 Arguments, no return
		*/
		template<typename P0, typename P1, typename P2, typename P3, typename P4>
		void			callFunction(const char* name, P0 arg1, P1 arg2, P2 arg3, P3 arg4, P4 arg5);
		/*
		//	Call a Function in the Script
		//	6 Arguments, no return
		*/
		template<typename P0, typename P1, typename P2, typename P3, typename P4, typename P5>
		void			callFunction(const char* name, P0 arg1, P1 arg2, P2 arg3, P3 arg4, P4 arg5, P5 arg6);
		/*
		//	Call a Function in the Script
		//	7 Arguments, no return
		*/
		template<typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
		void			callFunction(const char* name, P0 arg1, P1 arg2, P2 arg3, P3 arg4, P4 arg5, P5 arg6, P6 arg7);



		/*
		//	Call a Function in the Script
		//	0 Arguments, return
		*/
		template<typename R>
		R				callFunctionR(const char* name);
		/*
		//	Call a Function in the Script
		//	1 Arguments, return
		*/
		template<typename R, typename P0>
		R				callFunctionR(const char* name, P0 arg1);
		/*
		//	Call a Function in the Script
		//	2 Arguments, return
		*/
		template<typename R, typename P0, typename P1>
		R				callFunctionR(const char* name, P0 arg1, P1 arg2);
		/*
		//	Call a Function in the Script
		//	3 Arguments, return
		*/
		template<typename R, typename P0, typename P1, typename P2>
		R				callFunctionR(const char* name, P0 arg1, P1 arg2, P2 arg3);
		/*
		//	Call a Function in the Script
		//	4 Arguments, return
		*/
		template<typename R, typename P0, typename P1, typename P2, typename P3>
		R				callFunctionR(const char* name, P0 arg1, P1 arg2, P2 arg3, P3 arg4);
		/*
		//	Call a Function in the Script
		//	5 Arguments, return
		*/
		template<typename R, typename P0, typename P1, typename P2, typename P3, typename P4>
		R				callFunctionR(const char* name, P0 arg1, P1 arg2, P2 arg3, P3 arg4, P4 arg5);
		/*
		//	Call a Function in the Script
		//	6 Arguments, return
		*/
		template<typename R, typename P0, typename P1, typename P2, typename P3, typename P4, typename P5>
		R				callFunctionR(const char* name, P0 arg1, P1 arg2, P2 arg3, P3 arg4, P4 arg5, P5 arg6);
		/*
		//	Call a Function in the Script
		//	7 Arguments, return
		*/
		template<typename R, typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
		R				callFunctionR(const char* name, P0 arg1, P1 arg2, P2 arg3, P3 arg4, P4 arg5, P5 arg6, P6 arg7);
	
	private:
		char*			m_FilePath;
		size_t			m_PathLength;
		bool			m_bIsLoaded;
		LuaRef			m_Ref;
	};

}

#include "LuaScript.inl"
#endif